package ring

type Ring struct {
	prev, next *Ring
	Value      interface{}
}

func (o *Ring) init() *Ring {
	o.prev = o
	o.next = o
	return o
}

func New(n int) *Ring {
	if n <= 0 {
		return nil
	}
	o := new(Ring)
	p := o
	for i := 1; i < n; i++ {
		p.next = &Ring{prev: p}
		p = p.next
	}
	o.prev = p
	p.next = o

	return o
}

func (o *Ring) Next() *Ring {
	if o.next == nil {
		return o.init()
	}
	return o.next
}

func (o *Ring) Prev() *Ring {
	if o.prev == nil {
		return o.init()
	}
	return o.prev
}

func (o *Ring) Link(other *Ring) *Ring {
	n := o.Next()
	if other != nil {
		p := other.Prev()

		o.next = other
		other.prev = o

		n.prev = p
		p.next = n
	}
	return n
}

func (o *Ring) Move(n int) *Ring {
	if o.next == nil {
		return o.init()
	}
	switch {
	case n > 0:
		for ; n > 0; n-- {
			o = o.next
		}
	case n < 0:
		for ; n < 0; n++ {
			o = o.prev
		}
	}
	return o
}

func (o *Ring) UnLink(n int) *Ring {
	if n <= 0 {
		return nil
	}
	return o.Link(o.Move(n + 1))
}

func (o *Ring) Do(f func(interface{})) {
	if o != nil {
		f(o.Value)
		for p := o.Next(); p != o; p = p.next {
			f(p.Value)
		}
	}
}
